package com.ladlee.parking.pay.v3.core;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import com.ladlee.parking.pay.v3.enums.RequestMethod;
import com.ladlee.parking.pay.v3.enums.WxApiType;
import com.ladlee.parking.pay.v3.enums.WxDomain;
import com.ladlee.parking.pay.v3.util.WxPayKit;
import com.ladlee.parking.util.HttpKit;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付相关接口
 */
public class WxPayApi {

    /**
     * 获取接口请求的 URL
     *
     * @param wxApiType {@link WxApiType} 支付 API 接口枚举
     * @return {@link String} 返回完整的接口请求URL
     */
    public static String getReqUrl(WxApiType wxApiType) {
        return getReqUrl(wxApiType, null, false);
    }

    /**
     * 获取接口请求的 URL
     *
     * @param wxApiType {@link WxApiType} 支付 API 接口枚举
     * @param isSandBox 是否是沙箱环境
     * @return {@link String} 返回完整的接口请求URL
     */
    public static String getReqUrl(WxApiType wxApiType, boolean isSandBox) {
        return getReqUrl(wxApiType, null, isSandBox);
    }

    /**
     * 获取接口请求的URL
     *
     * @param wxApiType 支付 API 接口枚举
     * @param wxDomain  支付 API 接口域名枚举
     * @param isSandBox 是否是沙箱环境
     * @return 返回完整的接口请求URL
     */
    public static String getReqUrl(WxApiType wxApiType, WxDomain wxDomain, boolean isSandBox) {
        if (wxDomain == null) {
            wxDomain = WxDomain.CHINA;
        }
        return wxDomain.getType().concat(isSandBox ? WxApiType.SAND_BOX_NEW.getType() : "").concat(wxApiType.getType());
    }

    /**
     * @param method       请求方法
     * @param urlPrefix    可通过 {@link WxDomain}来获取
     * @param urlSuffix    可通过 {@link WxApiType} 来获取，URL挂载参数需要自行拼接
     * @param mchId        商户Id
     * @param serialNo     商户 API 证书序列号
     * @param platSerialNo 平台序列号
     * @param keyPath      apiclient_key.pem 证书路径
     * @param body         接口请求参数
     * @return
     */
    public static PayHttpResponse v3(RequestMethod method, String urlPrefix, String urlSuffix, String mchId,
                                     String serialNo, String platSerialNo, String keyPath, String body) throws Exception {
        // 时间戳
        long timestamp = System.currentTimeMillis() / 1000;
        // 认证类型
        // 微信支付商户API v3要求请求通过HTTPAuthorization头来传递签名。Authorization由认证类型和签名信息两个部分组成。Authorization: 认证类型 签名信息
        String authType = "WECHATPAY2-SHA256-RSA2048";
        // 随机字符串
        String nonceStr = WxPayKit.generateStr();
        return v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, body, nonceStr, timestamp, authType, null);
    }

    /**
     * V3 接口统一执行入口
     *
     * @param method       {@link RequestMethod} 请求方法
     * @param urlPrefix    可通过 {@link WxDomain}来获取
     * @param urlSuffix    可通过 {@link WxApiType} 来获取，URL挂载参数需要自行拼接
     * @param mchId        商户Id
     * @param serialNo     商户 API 证书序列号
     * @param platSerialNo 平台序列号，接口中包含敏感信息时必传
     * @param keyPath      apiclient_key.pem 证书路径
     * @param body         接口请求参数
     * @param nonceStr     随机字符库
     * @param timestamp    时间戳
     * @param authType     认证类型
     * @param file         文件
     * @return {@link PayHttpResponse} 请求返回的结果
     * @throws Exception 接口执行异常
     */
    public static PayHttpResponse v3(RequestMethod method, String urlPrefix, String urlSuffix, String mchId, String serialNo, String platSerialNo, String keyPath,
                                     String body, String nonceStr, long timestamp, String authType, File file) throws Exception {
        // 构建Authorization请求头
        String authorization = WxPayKit.buildAuthorization(method, urlSuffix, mchId, serialNo,
                keyPath, body, nonceStr, timestamp, authType);
        if (StrUtil.isEmpty(platSerialNo)) {
            platSerialNo = serialNo;
        }
        if (method == RequestMethod.GET) {

        } else if (method == RequestMethod.POST) {

        } else if (method == RequestMethod.DELETE) {

        } else if (method == RequestMethod.PUT) {

        } else if (method == RequestMethod.UPLOAD) {

        }
        return null;
    }

    public static PayHttpResponse post(String url, String authorization, String serialNumber, String data) {
        return post(url, data, getHeaders(authorization, serialNumber));
    }

    public static PayHttpResponse post(String url, String data, Map<String, String> headers) {
        return HttpKit.getDelegate().post(url, data, headers);
    }

    public static Map<String, String> getHeaders(String authorization, String serialNumber) {
        Map<String, String> headers = getBaseHeaders(authorization);
        headers.put("Content-Type", ContentType.JSON.toString());
        if (StrUtil.isNotEmpty(serialNumber)) {
            headers.put("Wechatpay-Serial", serialNumber);
        }
        return headers;
    }

    public static Map<String, String> getBaseHeaders(String authorization) {
        Map<String, String> headers = new HashMap<>(5);
        headers.put("Accept", ContentType.JSON.toString());
        headers.put("Authorization", authorization);
//        headers.put("User-Agent", userAgent);
        return headers;
    }
}
